package com.boarsoft.message.broker;

import com.boarsoft.message.bean.*;
import org.apache.activemq.broker.jmx.BrokerViewMBean;
import org.apache.activemq.broker.jmx.QueueViewMBean;
import org.springframework.stereotype.Component;

import javax.management.MBeanServerConnection;
import javax.management.MBeanServerInvocationHandler;
import javax.management.ObjectName;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component("amqBroker")
public class AmqBrokerImpl implements MessageBroker {

    public static long lastEnqueueCount;
    public static long lastDequeueCount;
    public String jmxServiceUrl="service:jmx:rmi:///jndi/rmi://localhost:11099/jmxrmi";
    public String brokerObjectName="org.apache.activemq:brokerName=localhost,type=Broker";


    @Override
    public Object addTargetQueue(String key, String xml) {
        return null;
    }

    @Override
    public Object activeTargetQueue(String key) {
        return null;
    }

    @Override
    public Object deactiveTargetQueue(String key) {
        return null;
    }

    @Override
    public Object activeRecipientQueue(String key) {
        return null;
    }

    @Override
    public Object deactiveRecipientQueue(String key) {
        return null;
    }

    @Override
    public Object removeTargetQueue(String key, boolean force) {
        return null;
    }

    @Override
    public Object updateTargetQueue(String code, String xml) {
        return null;
    }

    @Override
    public Object updateRecipientQueue(String code, String xml) throws Throwable {
        return null;
    }

    @Override
    public Object addRecipientQueue(String key, String xml) throws Throwable {
        return null;
    }

    @Override
    public Object removeRecipientQueue(String key, boolean force) {
        return null;
    }

    @Override
    public Object addTargetQueue(String key, TargetMQ tq) {
        return null;
    }

    @Override
    public Object statTargetQueue() {
        return this.getTargetQueue();
    }

    @Override
    public Object statTargetQueue(String target){
        Map<String, MessageQueueStat> rm = new HashMap<>();
        MessageQueueStat messageQueueStat = new MessageQueueStat();
        try {
            JMXServiceURL url = new JMXServiceURL(jmxServiceUrl);
            try (JMXConnector connector = JMXConnectorFactory.connect(url, null)) {
                MBeanServerConnection connection = connector.getMBeanServerConnection();

                ObjectName activeMQ = new ObjectName(brokerObjectName);
                BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(
                        connection, activeMQ, BrokerViewMBean.class, true);

                for (ObjectName name : mbean.getQueues()) {
                    QueueViewMBean queueMbean = MBeanServerInvocationHandler.newProxyInstance(
                            connection, name, QueueViewMBean.class, true);
                    if(target.equals(queueMbean.getName())) {
                        long initialEnqueueCount = queueMbean.getEnqueueCount();
                        long initialDequeueCount = queueMbean.getDequeueCount();
                        messageQueueStat.setIn((initialEnqueueCount+initialDequeueCount)-(lastEnqueueCount+lastDequeueCount));
                        messageQueueStat.setOut(lastDequeueCount-initialDequeueCount);
                        messageQueueStat.setSize(initialEnqueueCount);
                        lastEnqueueCount=initialEnqueueCount;
                        lastDequeueCount=initialDequeueCount;
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        rm.put("amq",messageQueueStat);
        return rm;
    }

    @Override
    public Object statRecipientQueue() {
        return null;
    }

    @Override
    public Object statRecipientQueue(String target) {
        return null;
    }

    @Override
    public Map<String, TargetQueueInfo> getTargetQueue() {
        Map<String, TargetQueueInfo> rm = new HashMap<String, TargetQueueInfo>();
        try {
            JMXServiceURL url = new JMXServiceURL(jmxServiceUrl);
            try (JMXConnector connector = JMXConnectorFactory.connect(url, null)) {
                MBeanServerConnection connection = connector.getMBeanServerConnection();

                ObjectName activeMQ = new ObjectName(brokerObjectName);
                BrokerViewMBean mbean = MBeanServerInvocationHandler.newProxyInstance(
                        connection, activeMQ, BrokerViewMBean.class, true);

                for (ObjectName name : mbean.getQueues()) {
                    QueueViewMBean queueMbean = MBeanServerInvocationHandler.newProxyInstance(
                            connection, name, QueueViewMBean.class, true);
                    TargetQueueInfo r = new TargetQueueInfo();
                    r.setName(queueMbean.getName());
                    rm.put(queueMbean.getName(), r);
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return rm;
    }

    @Override
    public List<MessageEntity> query(String target, MessageQueryParam mqp) {
        return null;
    }

    @Override
    public Object count(String target, MessageQueryParam mqp) {
        return null;
    }

    public String getJmxServiceUrl() {
        return jmxServiceUrl;
    }

    public void setJmxServiceUrl(String jmxServiceUrl) {
        this.jmxServiceUrl = jmxServiceUrl;
    }

    public String getBrokerObjectName() {
        return brokerObjectName;
    }

    public void setBrokerObjectName(String brokerObjectName) {
        this.brokerObjectName = brokerObjectName;
    }
}
